//
//  PHLocation.m
//  PhnixHome
//
//  Created by Levy Xu on 2018/1/3.
//  Copyright © 2018年 Levy Xu. All rights reserved.
//

#import "PHLocation.h"

@interface PHLocation()<CLLocationManagerDelegate>
@property(nonatomic, strong) CLLocationManager *locationManager;
@property(nonatomic, strong) CLGeocoder *geocoder;
@property(nonatomic, copy) PHLocationBlock block;
@property(nonatomic, strong) KKTimer *timer;
@property(nonatomic, assign) BOOL started;
@end

@implementation PHLocation

SingletonM(PHLocation, )

-(void)locationWithBlock:(PHLocationBlock)block {
    if (_started) {
        block(nil);
        return;
    }
    
    if (![CLLocationManager locationServicesEnabled]) {
        [KKAlert warningWithText:NSLocalizedString(@"tips_location_disabled", nil)];
        block(nil);
        return;
    }
    if (!_geocoder) {
        _geocoder = [[CLGeocoder alloc] init];
    }
    if (!_locationManager) {
        _locationManager = [[CLLocationManager alloc] init];
        _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        _locationManager.distanceFilter = 10.0;
    }
    
    _locationManager.delegate = self;
    
    NSInteger status = [CLLocationManager authorizationStatus];
    LOG(@"status %ld",(long)status);
    if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusAuthorizedAlways) {
        _block = [block copy];
        [self startLocation];
    } else if (status == kCLAuthorizationStatusNotDetermined) {
        _block = [block copy];
        [_locationManager requestWhenInUseAuthorization];
    } else {
        WS(ws);
        [KKAlert warningWithText:NSLocalizedString(@"tips_location_unauthorized", nil) cancel:^{
            block(nil);
        } ok:^{
            [KKUtils go2Settings];
            
            ws.block = [block copy];
            ws.timer = [KKTimer once:10.0 task:^(NSUInteger times) {
                ws.block(nil);
            }];
        }];
    }
}

-(void)startLocation {
    _started = YES;
    [_locationManager startUpdatingLocation];
    
    if (_timer && _timer.isValid) {
        [_timer invalidate];
        _timer = nil;
    }
    
    WS(ws);
    _timer = [KKTimer once:10.0f task:^(NSUInteger times) {
        [ws stopWithPlacemark:nil];
    }];
}

-(void)stopWithPlacemark:(CLPlacemark *)placemark {
    if (_block) {
        _block(placemark);
        _block = nil;
    }
    
    _started = NO;
    [_locationManager stopUpdatingLocation];
    _locationManager.delegate = nil;
    
    if (_timer && _timer.isValid) {
        [_timer invalidate];
        _timer = nil;
    }
}

#pragma mark - CLLocationManagerDelegate methods
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    LOG(@"%@", error.localizedDescription);
    [self stopWithPlacemark:nil];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
    WS(ws);
    CLLocation *location = locations.lastObject;
    LOG(@"精度：%.2f, 纬度：%.2f", location.coordinate.latitude, location.coordinate.longitude);
    if (!_geocoder.isGeocoding) {
        [_geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
            if (error) {
                LOG(@"%@", error.localizedDescription);
            } else {
                CLPlacemark *placemark = [placemarks firstObject];
                [ws stopWithPlacemark:placemark];
            }
        }];
    }
}

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    LOG(@"status %d",status);
    switch (status) {
        case kCLAuthorizationStatusNotDetermined:
            break;
        case kCLAuthorizationStatusDenied:
        case kCLAuthorizationStatusRestricted:
            if (_started) {
                [self stopWithPlacemark:nil];
            } else {
                !_block ?: _block(nil);
            }
            break;
        case kCLAuthorizationStatusAuthorizedAlways:
        case kCLAuthorizationStatusAuthorizedWhenInUse:
            if (!_started) {
                [self startLocation];
            }
            break;
    }
}
@end
